package com.sc.nft.admin.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.admin.request.IdRequest;
import com.sc.nft.admin.request.ScrollDetailPageRequest;
import com.sc.nft.admin.request.ScrollShopPageRequest;
import com.sc.nft.admin.request.ShopNameRequest;
import com.sc.nft.admin.vo.ScrollConfigDTO;
import com.sc.nft.annotation.SysMemberLogin;
import com.sc.nft.annotation.UserLogin;
import com.sc.nft.dao.*;
import com.sc.nft.dto.ShopPageVO;
import com.sc.nft.dto.ShopWantBuyOrderPageVO;
import com.sc.nft.dto.ShopWantSellOrderPageVO;
import com.sc.nft.dto.WantBuyOrderPageDetailVO;
import com.sc.nft.entity.*;
import com.sc.nft.enums.RedisKeyEnum;
import com.sc.nft.mapper.ScrollShopMapper;
import com.sc.nft.mapper.ScrollWantBuyMapper;
import com.sc.nft.mapper.ScrollWantSellMapper;
import com.sc.nft.mapper.SecondEquityPropsOrderMapper;
import com.sc.nft.service.ScrollWantBuyService;
import com.sc.nft.service.ScrollWantSellService;
import com.sc.nft.sup.ErrorCode;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;


@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/scrollShop")
@Api(tags = "")
public class ScrollShopAdminController {

    private final ScrollConfigDao scrollConfigDao;
    private final ScrollShopDao scrollShopDao;
    private final ScrollShopMapper scrollShopMapper;
    private final ScrollWantBuyMapper wantBuyMapper;
    private final ScrollWantSellMapper wantSellMapper;
    private final StaticDataDao staticDataDao;
    private final EquityPropsDao equityPropsDao;
    private final SecondEquityPropsOrderMapper secondEquityPropsOrderMapper;
    private final Redisson redisson;
    private final ScrollWantBuyService scrollWantBuyService;
    private final ScrollWantBuyDao scrollWantBuyDao;
    private final ScrollWantSellService scrollWantSellService;
    private final ScrollWantSellDao scrollWantSellDao;
    private final UserInfoDao userInfoDao;

    @ApiOperation(value = "获取配置", notes = "获取配置", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/getConfig", produces = MediaType.APPLICATION_JSON_VALUE)
    public Result<ScrollConfigDTO> getConfig() throws Exception {
        ScrollConfig config = scrollConfigDao.getConfig();
        ScrollConfigDTO dto = BeanUtil.toBean(config, ScrollConfigDTO.class);
        dto.setInDaoFee(dto.getInDaoFee().multiply(BigDecimal.valueOf(100)));
        dto.setOutDaoRatio(dto.getOutDaoRatio().multiply(BigDecimal.valueOf(100)));
        dto.setPlatformShareRatio(dto.getPlatformShareRatio().multiply(BigDecimal.valueOf(100)));
        dto.setSalesFeeRatio(dto.getSalesFeeRatio().multiply(BigDecimal.valueOf(100)));
        dto.setPropsShareRatio(dto.getPropsShareRatio().multiply(BigDecimal.valueOf(100)));
        dto.setShareholderShareRatio(dto.getShareholderShareRatio().multiply(BigDecimal.valueOf(100)));
        dto.setStaffShareRatio(dto.getStaffShareRatio().multiply(BigDecimal.valueOf(100)));
        dto.setMetaMapProvinceRatio(config.getMetaMapRatio());
        dto.setMetaMapCityRatio(dto.getMetaMapCityRatio());
        dto.setMetaMapRegionRatio(dto.getMetaMapRegionRatio());
        dto.setSalesOrderMaxCount(dto.getSalesOrderMaxCount());
        dto.setBuyOrderMaxCount(dto.getBuyOrderMaxCount());
        dto.setSalesFreezeCount(dto.getSalesFreezeCount());
        return Result.success(dto);
    }

    @ApiOperation(value = "更新配置", notes = "更新配置", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/updateConfig", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result updateConfig(@RequestBody ScrollConfigDTO dto) throws Exception {
        dto.checkRatio();
        ScrollConfig config = BeanUtil.toBean(dto, ScrollConfig.class);
        config.setId(1L);
        config.setInDaoFee(dto.getInDaoFee().divide(BigDecimal.valueOf(100)));
        config.setOutDaoRatio(dto.getOutDaoRatio().divide(BigDecimal.valueOf(100)));
        config.setPlatformShareRatio(dto.getPlatformShareRatio().divide(BigDecimal.valueOf(100)));
        config.setSalesFeeRatio(dto.getSalesFeeRatio().divide(BigDecimal.valueOf(100)));
        config.setPropsShareRatio(dto.getPropsShareRatio().divide(BigDecimal.valueOf(100)));
        config.setShareholderShareRatio(dto.getShareholderShareRatio().divide(BigDecimal.valueOf(100)));
        config.setStaffShareRatio(dto.getStaffShareRatio().divide(BigDecimal.valueOf(100)));
        config.setMetaMapRatio(dto.getMetaMapProvinceRatio());
        config.setMetaMapCityRatio(dto.getMetaMapCityRatio());
        config.setMetaMapRegionRatio(dto.getMetaMapRegionRatio());
        config.setSalesOrderMaxCount(dto.getSalesOrderMaxCount());
        config.setBuyOrderMaxCount(dto.getBuyOrderMaxCount());
        config.setSalesFreezeCount(dto.getSalesFreezeCount());
        config.updateById();
        return Result.success();
    }

    @ApiOperation(value = "设置店铺名称", notes = "设置店铺名称", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/setShopName", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result setShopName(@Valid @RequestBody ShopNameRequest dto) throws Exception {
        ScrollShop scrollShop = scrollShopDao.getById(dto.getId());
        if (ObjectUtil.isNull(scrollShop)) {
            return Result.fail("店铺不存在");
        }
        if (scrollShopDao.checkNameExists(dto.getShopName())) {
            return Result.fail("店铺名称已存在");
        }
        scrollShopDao.updateShopName(dto.getId(), dto.getShopName());
        return Result.success();
    }

    @ApiOperation(value = "冻结店铺", notes = "冻结店铺", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/onFreeze", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result onFreeze(@Valid @RequestBody IdRequest dto) throws Exception {
        ScrollShop scrollShop = scrollShopDao.getById(dto.getId());
        if (ObjectUtil.isNull(scrollShop)) {
            return Result.fail("店铺不存在");
        }
        scrollShopDao.updateFreezeStatus(dto.getId(), true);
        return Result.success();
    }

    @ApiOperation(value = "解冻店铺", notes = "解冻店铺", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/offFreeze", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result offFreeze(@Valid @RequestBody IdRequest dto) throws Exception {
        ScrollShop scrollShop = scrollShopDao.getById(dto.getId());
        if (ObjectUtil.isNull(scrollShop)) {
            return Result.fail("店铺不存在");
        }
        scrollShopDao.updateFreezeStatus(dto.getId(), false);
        return Result.success();
    }

    @ApiOperation(value = "店铺列表", notes = "店铺列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/shopPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<ShopPageVO> shopPage(@Valid @RequestBody ScrollShopPageRequest dto) throws Exception {
        return PageResult.success(scrollShopMapper.selectShopPage(dto.toMp(), dto.getShopName(), dto.getShopNum(), dto.getUserTel()));
    }


    @ApiOperation(value = "求购单列表", notes = "求购单列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/wantBuyOrderPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<ShopWantBuyOrderPageVO> wantBuyOrderPage(@Valid @RequestBody ScrollShopPageRequest dto) throws Exception {
        StaticData equityPropsId = staticDataDao.getByType("scroll_props_id");
        EquityProps eq = equityPropsDao.getById(Long.parseLong(equityPropsId.getValue()));
        Page<ShopWantBuyOrderPageVO> page = wantBuyMapper.wantBuyOrderPage(dto.toMp(), dto.getShopName(), dto.getShopNum(), dto.getUserTel());
        for (ShopWantBuyOrderPageVO record : page.getRecords()) {
            record.setName(eq.getFirstTitle());
        }
        return PageResult.success(page);
    }

    @ApiOperation(value = "求购单列表详情", notes = "求购单列表详情", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/wantBuyOrderPageDetail", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<WantBuyOrderPageDetailVO> wantBuyOrderPageDetail(@Valid @RequestBody ScrollDetailPageRequest dto) throws Exception {
        return PageResult.success(secondEquityPropsOrderMapper.wantBuyOrderPage(dto.toMp(), dto.getId(), dto.getUserTel(), dto.getStartOrderTime(), dto.getEndOrderTime(), dto.getStartPayTime(), dto.getEndPayTime()));
    }

    @ApiOperation(value = "出售单列表", notes = "出售单列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/wantSellOrderPage", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<ShopWantSellOrderPageVO> wantSellOrderPage(@Valid @RequestBody ScrollShopPageRequest dto) throws Exception {

        StaticData equityPropsId = staticDataDao.getByType("scroll_props_id");
        EquityProps eq = equityPropsDao.getById(Long.parseLong(equityPropsId.getValue()));
        Page<ShopWantSellOrderPageVO> page = wantSellMapper.wantSellOrderPage(dto.toMp(), dto.getShopName(), dto.getShopNum(), dto.getUserTel());
        for (ShopWantSellOrderPageVO record : page.getRecords()) {
            record.setName(eq.getFirstTitle());
        }
        return PageResult.success(page);
    }

    @ApiOperation(value = "关闭出售订单", notes = "关闭出售订单", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/closeSellsOrder", produces = MediaType.APPLICATION_JSON_VALUE)
    @UserLogin
    public Result closeSellsOrder(@Valid @RequestBody IdRequest request) {
        ScrollWantSell wantSell = scrollWantSellDao.getById(request.getId());
        UserInfo userInfo = userInfoDao.getById(wantSell.getShopUserId());
        RLock lock = redisson.getLock(RedisKeyEnum.SCROLL_SHOP_SELL_ORDER.getKey() + request.getId());
        try {
            boolean res = lock.tryLock(30, TimeUnit.SECONDS);
            if (res) {
                scrollWantSellService.closeWantSellOrder(request.getId(), userInfo, userInfo.getTransactionPassword());
            } else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            return Result.fail("当前人数过多，请稍后再试");
        } finally {
            lock.unlock();
        }
        return Result.success();
    }

    @ApiOperation(value = "求购单关闭", notes = "求购单关闭", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/wantBuyClose", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result wantBuyClose(@Valid @RequestBody IdRequest request) {
        ScrollWantBuy wantBuy = scrollWantBuyDao.getById(request.getId());
        UserInfo userInfo = userInfoDao.getById(wantBuy.getShopUserId());
        RLock lock = redisson.getLock(RedisKeyEnum.SCROLL_SHOP_ORDER.getKey() + request.getId());
        try {
            boolean res = lock.tryLock(30, TimeUnit.SECONDS);
            if (res) {
                scrollWantBuyService.closeWantBuyOrder(request.getId(), userInfo, userInfo.getTransactionPassword());
            } else {
                return Result.fail(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            return Result.fail("当前人数过多，请稍后再试");
        } finally {
            lock.unlock();
        }
        return Result.success();
    }

    @ApiOperation(value = "出售单列表详情", notes = "出售单列表详情", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/wantSellOrderPageDetail", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<WantBuyOrderPageDetailVO> wantSellOrderPageDetail(@RequestBody ScrollDetailPageRequest dto) throws Exception {
        return PageResult.success(secondEquityPropsOrderMapper.wantSellOrderPage(dto.toMp(), dto.getId(), dto.getUserTel(), dto.getStartOrderTime(), dto.getEndOrderTime(), dto.getStartPayTime(), dto.getEndPayTime()));
    }

}
